//****************************************Copyright (c)***********************************//
//****************************************************************************************//

module dual_ov5640_lcd(    
    input         sys_clk    ,  //系统时钟
    input         sys_rst_n  ,  //系统复位，低电平有效
    //摄像头0 
    input         cam0_pclk  ,  //cmos 数据像素时钟
    input         cam0_vsync ,  //cmos 场同步信号
    input         cam0_href  ,  //cmos 行同步信号
    input  [7:0]  cam0_data  ,  //cmos 数据  
    output        cam0_rst_n ,  //cmos 复位信号，低电平有效
    output        cam0_pwdn  ,  //cmos 电源休眠模式选择信号
    output        cam0_scl   ,  //cmos SCCB_SCL线
    inout         cam0_sda   ,  //cmos SCCB_SDA线
    
    //摄像头1 
    input         cam1_pclk  ,  //cmos 数据像素时钟
    input         cam1_vsync ,  //cmos 场同步信号
    input         cam1_href  ,  //cmos 行同步信号
    input  [7:0]  cam1_data  ,  //cmos 数据  
    output        cam1_rst_n ,  //cmos 复位信号，低电平有效
    output        cam1_pwdn  ,  //cmos 电源休眠模式选择信号
    output        cam1_scl   ,  //cmos SCCB_SCL线
    inout         cam1_sda   ,  //cmos SCCB_SDA线
    output        eth_rst    ,    
    //SDRAM 
    output        sdram_clk  ,  //SDRAM 时钟
    output        sdram_cke  ,  //SDRAM 时钟有效
    output        sdram_cs_n ,  //SDRAM 片选
    output        sdram_ras_n,  //SDRAM 行有效
    output        sdram_cas_n,  //SDRAM 列有效
    output        sdram_we_n ,  //SDRAM 写有效
    output [1:0]  sdram_ba   ,  //SDRAM Bank地址
    output [1:0]  sdram_dqm  ,  //SDRAM 数据掩码
    output [12:0] sdram_addr ,  //SDRAM 地址
    inout  [15:0] sdram_data ,  //SDRAM 数据    
    //LCD                   
    output        lcd_hs     ,  //LCD 行同步信号
    output        lcd_vs     ,  //LCD 场同步信号
    output        lcd_de     ,  //LCD 数据输入使能
    inout  [15:0] lcd_rgb    ,  //LCD RGB565颜色数据
    output        lcd_bl     ,  //LCD 背光控制信号
    output        lcd_rst    ,  //LCD 复位信号
    output        lcd_pclk  ,    //LCD 采样时钟
	 //按键
	 output         led_1, 
    input        key_1,           //按键信号    
	 output         led_2, 
    input        key_2           //按键信号  
    );

//wire define
wire        clk_100m       ;  //100mhz时钟,SDRAM操作时钟
wire        clk_100m_shift ;  //100mhz时钟,SDRAM相位偏移时钟
wire        clk_50m_lcd    ;
wire        clk_lcd        ;  
wire        locked         ;
wire        rst_n          ;
wire        sys_init_done  ;  //系统初始化完成(sdram初始化+摄像头初始化)
                    
wire        cam0_init_done ;
wire        cam1_init_done ;
                    
wire        wr0_en         ;  //sdram_ctrl模块写使能
wire [15:0] wr0_data       ;  //sdram_ctrl模块写数据
wire        wr1_en         ;  //sdram_ctrl模块写使能
wire [15:0] wr1_data       ;  //sdram_ctrl模块写数据
wire        rd_en          ;  //sdram_ctrl模块读使能
wire [15:0] rd_data        ;  //sdram_ctrl模块读数据
wire [12:0] rd_h_pixel     ;  //图像水平像素
wire        sdram_init_done;  //SDRAM初始化完成

wire [15:0] lcd_id         ;  //LCD的ID

wire [12:0] cmos_h_pixel   ;  //CMOS水平方向像素个数 
wire [12:0] cmos_v_pixel   ;  //CMOS垂直方向像素个数
wire [12:0] total_h_pixel  ;  //水平总像素大小
wire [12:0] total_v_pixel  ;  //垂直总像素大小
wire [23:0] sdram_max_addr ;  //sdram读写的最大地址

//*****************************************************
//**                    main code
//*****************************************************

assign  rst_n = sys_rst_n & locked;
assign  eth_rst=0;
pll u_pll(
    .areset             (~sys_rst_n),
    .inclk0             (sys_clk),
            
    .c0                 (clk_100m),
    .c1                 (clk_100m_shift),
    .c2                 (clk_50m_lcd),
    .locked             (locked)
    );

//例化LCD顶层模块
lcd_rgb_top lcd_rgb_top(
	 
	 //按键
	 .key_1                (key_1),
	 .led_1            (led_1),
	 .key_2                (key_2),
	 .led_2            (led_2),
	 
    .clk                (clk_50m_lcd),
	 .sdram_init_done    (sdram_init_done),
    .rst_n              (rst_n),
	 //lcd接口	 
	 .lcd_id             (lcd_id),
    .lcd_hs             (lcd_hs),
    .lcd_vs             (lcd_vs),
    .lcd_de             (lcd_de),
    .lcd_rgb            (lcd_rgb),
    .lcd_bl             (lcd_bl),
    .lcd_rst            (lcd_rst),
    .lcd_pclk           (lcd_pclk), 
	 .clk_lcd            (clk_lcd) ,         //LCD驱动时钟
	 //用户接口
	 .rd_h_pixel         (cmos_h_pixel),
	 .out_vsync          (out_vsync),
	 .h_disp             (),                 //行分辨率  
    .v_disp             (),                 //场分辨率  
    .pixel_xpos         (),
    .pixel_ypos         (),	 
    .rd_data            (rd_data),
    .rd_en              (rd_en),                
    );
    
//摄像头图像分辨率设置模块
picture_size u_picture_size (
    .rst_n              (rst_n),

    .lcd_id             (lcd_id),           //LCD的ID，用于配置摄像头的图像大小
                        
    .cmos_h_pixel       (cmos_h_pixel  ),   //摄像头水平方向分辨率 
    .cmos_v_pixel       (cmos_v_pixel  ),   //摄像头垂直方向分辨率  
    .total_h_pixel      (total_h_pixel ),   //用于配置HTS寄存器
    .total_v_pixel      (total_v_pixel ),   //用于配置VTS寄存器
    .sdram_max_addr     (sdram_max_addr)    //sdram读写的最大地址
    );  

//OV5640 0摄像头驱动
ov5640_dri u0_ov5640_dri(
    .clk               (clk_100m),
    .rst_n             (rst_n),

    .cam_pclk          (cam0_pclk ),
    .cam_vsync         (cam0_vsync),
    .cam_href          (cam0_href ),
    .cam_data          (cam0_data ),
    .cam_rst_n         (cam0_rst_n),
    .cam_pwdn          (cam0_pwdn ),
    .cam_scl           (cam0_scl  ),
    .cam_sda           (cam0_sda  ),
    
    .capture_start     (sdram_init_done),
    .cmos_h_pixel      (cmos_h_pixel[12:1]),
    .cmos_v_pixel      (cmos_v_pixel),
    .total_h_pixel     (total_h_pixel),
    .total_v_pixel     (total_v_pixel),
   

    .cmos_frame_vsync  (),
    .cmos_frame_href   (),
    .cmos_frame_valid  (wr0_en),
    .cmos_frame_data   (wr0_data)
    );
    
//OV5640 1摄像头驱动
ov5640_dri u1_ov5640_dri(
    .clk               (clk_100m),
    .rst_n             (rst_n),
 
    .cam_pclk          (cam1_pclk ),
    .cam_vsync         (cam1_vsync),
    .cam_href          (cam1_href ),
    .cam_data          (cam1_data ),
    .cam_rst_n         (cam1_rst_n),
    .cam_pwdn          (cam1_pwdn ),
    .cam_scl           (cam1_scl  ),
    .cam_sda           (cam1_sda  ),
    
    .capture_start     (sdram_init_done),
    .cmos_h_pixel      (cmos_h_pixel[12:1]),
    .cmos_v_pixel      (cmos_v_pixel),
    .total_h_pixel     (total_h_pixel),
    .total_v_pixel     (total_v_pixel),
   

    .cmos_frame_vsync  (),
    .cmos_frame_href   (),
    .cmos_frame_valid  (wr1_en),
    .cmos_frame_data   (wr1_data)
    );    
    
//SDRAM 控制器顶层模块,封装成FIFO接口
//SDRAM 控制器地址组成: {bank_addr[1:0],row_addr[12:0],col_addr[8:0]}
sdram_top u_sdram_top(
    .ref_clk            (clk_100m),         //sdram 控制器参考时钟
    .out_clk            (clk_100m_shift),   //用于输出的相位偏移时钟
    .rst_n              (rst_n),            //系统复位
                                            
    //用户写端口    
    .wr_len             (10'd512),          //写SDRAM时的数据突发长度
    .wr_load            (~rst_n),           //写端口复位: 复位写地址,清空写FIFO    
    .wr_min_addr        (24'd0),            //写SDRAM的起始地址
    .wr_max_addr        (sdram_max_addr),   //写SDRAM的结束地址
    
    .wr_clk0            (cam0_pclk),        //写端口FIFO: 写时钟
    .wr_en0             (wr0_en),           //写端口FIFO: 写使能
    .wr_data0           (wr0_data),         //写端口FIFO: 写数据

    .wr_clk1            (cam1_pclk),        //写端口FIFO: 写时钟
    .wr_en1             (wr1_en),           //写端口FIFO: 写使能
    .wr_data1           (wr1_data),         //写端口FIFO: 写数据
    
    //用户读端口
    .rd_h_pixel         (cmos_h_pixel[12:1]),
    .rd_clk             (clk_lcd),          //读端口FIFO: 读时钟
    .rd_en              (rd_en),            //读端口FIFO: 读使能
    .rd_data            (rd_data),          //读端口FIFO: 读数据
    .rd_min_addr        (24'd0),            //读SDRAM的起始地址
    .rd_max_addr        (sdram_max_addr),   //读SDRAM的结束地址
    .rd_len             (10'd512),          //从SDRAM中读数据时的突发长度
    .rd_load            (~rst_n),           //读端口复位: 复位读地址,清空读FIFO
    
    //用户控制端口                                
    .sdram_read_valid   (1'b1),             //SDRAM 读使能
    .sdram_pingpang_en  (1'b1),             //SDRAM 乒乓操作使能
    .sdram_init_done    (sdram_init_done),  //SDRAM 初始化完成标志
                                            
    //SDRAM 芯片接口                                
    .sdram_clk          (sdram_clk),        //SDRAM 芯片时钟
    .sdram_cke          (sdram_cke),        //SDRAM 时钟有效
    .sdram_cs_n         (sdram_cs_n),       //SDRAM 片选
    .sdram_ras_n        (sdram_ras_n),      //SDRAM 行有效
    .sdram_cas_n        (sdram_cas_n),      //SDRAM 列有效
    .sdram_we_n         (sdram_we_n),       //SDRAM 写有效
    .sdram_ba           (sdram_ba),         //SDRAM Bank地址
    .sdram_addr         (sdram_addr),       //SDRAM 行/列地址
    .sdram_data         (sdram_data),       //SDRAM 数据
    .sdram_dqm          (sdram_dqm)         //SDRAM 数据掩码
    );

endmodule 